package eatwatch;

import java.util.*;
import javax.microedition.rms.*;

/**
 *	Uses the MIDP record store for data storage
 */
public final class DatabaseRecordStore implements IDatabase
{
	// private members
	private RecordStore			mRecordStore	= null;
	private DataDefinition 		mDataDefinition	= null;
	private RecordEnumeration	mRecEnumeration = null;

	// public interface
	public void	Open (String table)
	{
		if (mRecordStore != null)
			Close ();
		try {
			mRecordStore = RecordStore.openRecordStore (table, true);
			mRecEnumeration = mRecordStore.enumerateRecords (null, null, false);
			ReadDataDefinition ();
		}
		catch (RecordStoreException ex) { ex.printStackTrace (); }
	}

	public void	Open (String table, String sortField)
	{
		if (mRecordStore != null)
			Close ();
		try {
			mRecordStore = RecordStore.openRecordStore (table, true);
			ReadDataDefinition ();
			RecordComparator recordComparator = null;
			if (mDataDefinition != null)
				recordComparator = new FieldComparator (mDataDefinition, sortField);

			mRecEnumeration = mRecordStore.enumerateRecords (null, recordComparator, false);
		}
		catch (RecordStoreException ex) { ex.printStackTrace (); }
	}


	public void	Close ()
	{
		if (mRecordStore != null) try {
			mRecordStore.closeRecordStore ();
		}
		catch (RecordStoreException ignore) {}
		mRecordStore = null;
		mDataDefinition = null;
	}

	public void AddRecord (Record record)
	{
		if (mDataDefinition == null) {
			mDataDefinition = new DataDefinition (record);
			WriteDataDefinition ();
		}


		byte[] data = mDataDefinition.Write (record);
		try {
			mRecordStore.addRecord (data, 0, data.length);
		}
		catch (RecordStoreException ignore) {}
	}

	public Record ReadRecord ()
	{
		if (mRecEnumeration == null){
			System.out.println ("mRecEnumeration is null");
			return null;
		}
		if (mRecEnumeration.hasNextElement ()) try {
			int recordId = mRecEnumeration.nextRecordId ();
			Record record = mDataDefinition.Read (mRecordStore.getRecord (recordId));
			record.SetId (recordId);
			return record;
		}
		catch (RecordStoreException ignore) { }

		return null;
	}

	public Record  FindRecord (String field, Object value)
	{
		while (mRecEnumeration.hasNextElement ()) try {
			int recordId = mRecEnumeration.nextRecordId ();
			Record record = mDataDefinition.Read (mRecordStore.getRecord (recordId));
			record.SetId (recordId);
			if (FieldComparator.compare (record.GetField (field), value) == RecordComparator.EQUIVALENT)
				return record;
		}
		catch (RecordStoreException ignore) { }

		return null;
	}

	public void UpdateRecord (Record record)
	{
		byte[] data = mDataDefinition.Write (record);
		try {
			mRecordStore.setRecord (record.GetId (), data, 0, data.length);
		}
		catch (RecordStoreException ignore) {}
	}

	public void DeleteRecord (int recordId)
	{
		if (mRecordStore == null)
			throw new RuntimeException ("Database not open");

		try {
			mRecordStore.deleteRecord (recordId);
		}
		catch (RecordStoreException ignore) {}
	}

	private void WriteDataDefinition ()
	{
		try {
			RecordStore rs = RecordStore.openRecordStore (mRecordStore.getName () + "_dd", true);
			byte[] dataDD = mDataDefinition.GetDataDefinitionBytes ();
			rs.addRecord (dataDD, 0, dataDD.length);
		}
		catch (RecordStoreException ignore) { }
	}

	private void ReadDataDefinition ()
	{
		try {
			RecordStore rs = RecordStore.openRecordStore (mRecordStore.getName () + "_dd", true);
			RecordEnumeration re = rs.enumerateRecords (null, null, false);
			if (re.hasNextElement ())
				mDataDefinition = new DataDefinition (re.nextRecord ());
		}
		catch (RecordStoreException ignore) { }
	}
}